From: jchesterfield@dhcp92.uk.xensource.com Date: Thu, 5 Oct 2006 09:55:13 +0000 (+0100) Subject: [BLKTAP] Blktapctrl: Add asynchronous watch on dom0 name entry for blktapctrl on... X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~15615^2~48 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22Dat/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22Dat?a=commitdiff_plain;h=9bc9168a08bcea5965e1e0b2dfe7cbeefc7f28cd;p=xen.git [BLKTAP] Blktapctrl: Add asynchronous watch on dom0 name entry for blktapctrl on startup. This patch cleans up the synchronisation issues between blktapctrl and xend at initialisation if the Dom0 entries have not yet been populated. Signed-off-by: Julian Chesterfield --- diff --git a/tools/blktap/drivers/blktapctrl.c b/tools/blktap/drivers/blktapctrl.c index 60d999c78d..690c5de97f 100644 --- a/tools/blktap/drivers/blktapctrl.c +++ b/tools/blktap/drivers/blktapctrl.c @@ -669,6 +669,7 @@ int main(int argc, char *argv[]) goto open_failed; } + retry: /* Set up store connection and watch. */ h = xs_daemon_open(); @@ -682,15 +683,14 @@ int main(int argc, char *argv[]) } else goto open_failed; } - ret = add_blockdevice_probe_watch(h, "Domain-0"); - if (ret != 0) { + ret = setup_probe_watch(h); + if (ret < 0) { DPRINTF("Failed adding device probewatch\n"); - if (count < MAX_ATTEMPTS) { - count++; - sleep(2); - xs_daemon_close(h); - goto retry; - } else goto open_failed; + xs_daemon_close(h); + goto open_failed; + } else { + DPRINTF("Added probe %s\n", + (ret ? "ASYNCHRONOUSLY":"SYNCHRONOUSLY")); } ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_INTERPOSE ); diff --git a/tools/blktap/lib/blktaplib.h b/tools/blktap/lib/blktaplib.h index 7f1d4f1a94..456a368786 100644 --- a/tools/blktap/lib/blktaplib.h +++ b/tools/blktap/lib/blktaplib.h @@ -193,8 +193,8 @@ typedef struct msg_pid { #define CTLMSG_PID_RSP 10 /* xenstore/xenbus: */ -extern int add_blockdevice_probe_watch(struct xs_handle *h, - const char *domname); +#define DOMNAME "Domain-0" +int setup_probe_watch(struct xs_handle *h); int xs_fire_next_watch(struct xs_handle *h); diff --git a/tools/blktap/lib/xenbus.c b/tools/blktap/lib/xenbus.c index 91cdd00536..95b5f602ab 100644 --- a/tools/blktap/lib/xenbus.c +++ b/tools/blktap/lib/xenbus.c @@ -356,17 +356,12 @@ static void ueblktap_probe(struct xs_handle *h, struct xenbus_watch *w, *are created, we initalise the state and attach a disk. */ -int add_blockdevice_probe_watch(struct xs_handle *h, const char *domname) +int add_blockdevice_probe_watch(struct xs_handle *h, const char *domid) { - char *domid, *path; + char *path; struct xenbus_watch *vbd_watch; int er; - domid = get_dom_domid(h, domname); - - DPRINTF("%s: %s\n", - domname, (domid != NULL) ? domid : "[ not found! ]"); - asprintf(&path, "/local/domain/%s/backend/tap", domid); if (path == NULL) return -ENOMEM; @@ -385,3 +380,69 @@ int add_blockdevice_probe_watch(struct xs_handle *h, const char *domname) } return 0; } + +/* + *Asynch callback to check for /local/domain//name + */ +void check_dom(struct xs_handle *h, struct xenbus_watch *w, + const char *bepath_im) { + char *domid = NULL; + + domid = get_dom_domid(h); + if (domid) { + add_blockdevice_probe_watch(h, domid); + free(domid); + unregister_xenbus_watch(h, w); + } + return; +} + +/* + *We must wait for xend to register /local/domain/ + */ +int watch_for_domid(struct xs_handle *h) +{ + struct xenbus_watch *domid_watch; + char *path = NULL; + int er; + + asprintf(&path, "/local/domain"); + if (path == NULL) + return -ENOMEM; + + domid_watch = (struct xenbus_watch *)malloc(sizeof(struct xenbus_watch)); + if (!domid_watch) { + DPRINTF("ERROR: unable to malloc domid_watch [%s]\n", path); + return -EINVAL; + } + domid_watch->node = path; + domid_watch->callback = check_dom; + er = register_xenbus_watch(h, domid_watch); + if (er == 0) { + DPRINTF("ERROR: adding vbd probe watch %s\n", path); + return -EINVAL; + } + if (path == NULL) + return -ENOMEM; + return 1; +} + +int setup_probe_watch(struct xs_handle *h) +{ + char *domid = NULL, *path; + int ret; + + domid = get_dom_domid(h); + + if (!domid) { + /*Asynchronous path*/ + ret = watch_for_domid(h); + goto finish; + } else { + /*Synchronous path*/ + ret = add_blockdevice_probe_watch(h, domid); + free(domid); + } + finish: + return ret; +} diff --git a/tools/blktap/lib/xs_api.c b/tools/blktap/lib/xs_api.c index 054e9c850a..6d6a5fdfba 100644 --- a/tools/blktap/lib/xs_api.c +++ b/tools/blktap/lib/xs_api.c @@ -165,7 +165,7 @@ int xs_exists(struct xs_handle *h, const char *path) * This assumes that the domain name we are looking for is unique. * Name parameter Domain-0 */ -char *get_dom_domid(struct xs_handle *h, const char *name) +char *get_dom_domid(struct xs_handle *h) { char **e, *val, *domid = NULL; unsigned int num, len; @@ -187,7 +187,7 @@ char *get_dom_domid(struct xs_handle *h, const char *name) if (val == NULL) continue; - if (strcmp(val, name) == 0) { + if (strcmp(val, DOMNAME) == 0) { /* match! */ asprintf(&path, "/local/domain/%s/domid", e[i]); domid = xs_read(h, xth, path, &len); diff --git a/tools/blktap/lib/xs_api.h b/tools/blktap/lib/xs_api.h index c4183a2dde..34430dcc48 100644 --- a/tools/blktap/lib/xs_api.h +++ b/tools/blktap/lib/xs_api.h @@ -42,7 +42,7 @@ int xs_gather(struct xs_handle *xs, const char *dir, ...); int xs_printf(struct xs_handle *h, const char *dir, const char *node, const char *fmt, ...); int xs_exists(struct xs_handle *h, const char *path); -char *get_dom_domid(struct xs_handle *h, const char *name); +char *get_dom_domid(struct xs_handle *h); int convert_dev_name_to_num(char *name); int register_xenbus_watch(struct xs_handle *h, struct xenbus_watch *watch); int unregister_xenbus_watch(struct xs_handle *h, struct xenbus_watch *watch);